package Test1.GeneralFunction;

import Test1.HCNetSDK;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 语音对讲.
 */
public class VoiceTalk {
    static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo;//设备信息
    private static FVoiceDataCallBack fVoiceDataCallBack;//回调函数

    FileOutputStream fLocal;//本地音频文件
    FileOutputStream fDevice;//设备发送的音频文件

    /*************************************************
     * 函数:     VoiceTalk
     *************************************************/
    NativeLong g_lVoiceHandle;

    //开始对讲
    public NativeLong StartVoiceTalk(int lUserID, int lChennalNum, boolean bNeedCBNoEncData) {
        try
        {
            fLocal = new FileOutputStream("E:\\local.g7");
            fDevice = new FileOutputStream("E:\\device.g7");
        } catch (IOException ex)
        {
            Logger.getLogger(VoiceTalk.class.getName()).log(Level.SEVERE, null, ex);
        }
        HCNetSDK.NET_DVR_COMPRESSION_AUDIO struCOMPRESSION_AUDIO = new HCNetSDK.NET_DVR_COMPRESSION_AUDIO();
        struCOMPRESSION_AUDIO.write();
        IntByReference pInt = new IntByReference(0);

        if (!hCNetSDK.NET_DVR_GetDVRConfig(lUserID, 1058, new NativeLong(0xFFFFFFFF), struCOMPRESSION_AUDIO.getPointer(), struCOMPRESSION_AUDIO.size(), pInt)) {
            System.out.println("获取语音对讲参数失败，错误码：" + hCNetSDK.NET_DVR_GetLastError());
        }
        else
        {
            struCOMPRESSION_AUDIO.read();
            System.out.println("音频编码类型："+struCOMPRESSION_AUDIO.byAudioEncType + "音频采样率："+struCOMPRESSION_AUDIO.byAudioSamplingRate+ "音频码率："+ struCOMPRESSION_AUDIO.byAudioBitRate + "bySupport:"+struCOMPRESSION_AUDIO.bySupport);
        }

        if(fVoiceDataCallBack == null)
        {
            fVoiceDataCallBack = new FVoiceDataCallBack();
        }

        g_lVoiceHandle = hCNetSDK.NET_DVR_StartVoiceCom_V30(lUserID, lChennalNum, bNeedCBNoEncData, fVoiceDataCallBack, null);
        if (g_lVoiceHandle.intValue() == -1) {
            System.out.println("语音对讲失败");
        }
        else
        {
            System.out.println(g_lVoiceHandle);
        }
        return g_lVoiceHandle;
    }

    //停止对讲
    public void stopVoiceTalk(NativeLong g_lVoiceHandle) {
        if (g_lVoiceHandle.intValue() >= 0)
        {
            if (hCNetSDK.NET_DVR_StopVoiceCom(g_lVoiceHandle)) {
                try {
                    fLocal.close();
                    fDevice.close();
                } catch (IOException ex) {
                    Logger.getLogger(VoiceTalk.class.getName()).log(Level.SEVERE, null, ex);
                }
                g_lVoiceHandle.setValue(-1);
            } else {
                System.out.println("关闭对讲失败");
            }
        }
    }


    /******************************************************************************
     * 内部类:   FVoiceDataCallBack
     * 实现对讲音频数据回调
     ******************************************************************************/
    class FVoiceDataCallBack implements HCNetSDK.FVoiceDataCallback_V30 {
        //对对讲的音频数据进行回调操作,以下写入文件操作
        public void invoke(NativeLong lVoiceComHandle, Pointer pRecvDataBuffer, int dwBufSize, byte byAudioFlag, Pointer pUser) {
            //byAudioFlag为0表示本地文件,为1表示设备的音频文件
            if (byAudioFlag == 0) {
                try {
                    System.out.println("FVoiceDataCallBack 回调一个电脑发出的语音包");
                    fLocal.write(pRecvDataBuffer.getByteArray(0, dwBufSize), 0, dwBufSize);
                } catch (IOException ex) {
                    Logger.getLogger(VoiceTalk.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else {
                if (byAudioFlag == 1) {
                    try {
                        System.out.println("FVoiceDataCallBack 回调一个设备发来的语音包");
                        fDevice.write(pRecvDataBuffer.getByteArray(0, dwBufSize), 0, dwBufSize);

                    } catch (IOException ex) {
                        Logger.getLogger(VoiceTalk.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
    }
}
